#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdio.h>

#include "camera.h"

#define MOVE_INC_VALUE 0.05f
#define KEY_FORWARD_ACTION 1
#define KEY_BACKWARD_ACTION 2
#define KEY_STRAFE_LEFT_ACTION 4
#define KEY_STRAFE_RIGHT_ACTION 8
#define KEY_UP_ACTION 16
#define KEY_DOWN_ACTION 32
#define KEYS_FRONT_LEFT_ACTION 5
#define KEYS_FRONT_RIGHT_ACTION 9
#define KEYS_BACK_LEFT_ACTION 6
#define KEYS_BACK_RIGHT_ACTION 10

namespace control
{
	CCamera* controlled_camera = NULL;
	int PressedKeys = 0;
}

using namespace control;


void BindControlToCamera(CCamera* controlled_camera_point)
{
	controlled_camera = controlled_camera_point;
}

void KeyboardCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
	//static int PressedKeys
	if (controlled_camera == NULL)
	{
		printf("erro: keyboardcallback: nenhuma camera ligada ao teclado\n");
		return;
	}

	switch(action)
	{
		case GLFW_PRESS:
			switch(key)
			{
				case GLFW_KEY_ESCAPE:
					glfwSetWindowShouldClose(window, GL_TRUE);
					break;

				case GLFW_KEY_W:
					PressedKeys += KEY_FORWARD_ACTION;
					break;

				case GLFW_KEY_S:
					PressedKeys += KEY_BACKWARD_ACTION;
					break;

				case GLFW_KEY_A:
					PressedKeys += KEY_STRAFE_LEFT_ACTION;
					break;

				case GLFW_KEY_D:
					PressedKeys += KEY_STRAFE_RIGHT_ACTION;
					break;

				case GLFW_KEY_SPACE:
					PressedKeys += KEY_UP_ACTION;
					break;

				case GLFW_KEY_LEFT_CONTROL:
					PressedKeys += KEY_DOWN_ACTION;
					break;
			}
			break;

		case GLFW_RELEASE:
			switch(key)
			{
				case GLFW_KEY_W:
					PressedKeys -= KEY_FORWARD_ACTION;
					break;

				case GLFW_KEY_S:
					PressedKeys -= KEY_BACKWARD_ACTION;
					break;

				case GLFW_KEY_A:
					PressedKeys -= KEY_STRAFE_LEFT_ACTION;
					break;

				case GLFW_KEY_D:
					PressedKeys -= KEY_STRAFE_RIGHT_ACTION;
					break;

				case GLFW_KEY_SPACE:
					PressedKeys -= KEY_UP_ACTION;
					break;

				case GLFW_KEY_LEFT_CONTROL:
					PressedKeys -= KEY_DOWN_ACTION;
					break;
			}
			break;
	}
}

void TestFlag()
{
	switch(PressedKeys)
	{
		case KEY_FORWARD_ACTION:
			controlled_camera->MoveForward(MOVE_INC_VALUE);
			break;

		case KEY_BACKWARD_ACTION:
			controlled_camera->MoveBackward(MOVE_INC_VALUE);
			break;

		case KEY_STRAFE_LEFT_ACTION:
			controlled_camera->StrafeLeft(MOVE_INC_VALUE);
			break;

		case KEY_STRAFE_RIGHT_ACTION:
			controlled_camera->StrafeRight(MOVE_INC_VALUE);
			break;

		case KEY_UP_ACTION:
			controlled_camera->MoveUp(MOVE_INC_VALUE);
			break;

		case KEY_DOWN_ACTION:
			controlled_camera->MoveDown(MOVE_INC_VALUE);
			break;

		case KEYS_FRONT_LEFT_ACTION:
			controlled_camera->MoveForward(MOVE_INC_VALUE);
			controlled_camera->StrafeLeft(MOVE_INC_VALUE);
			break;

		case KEYS_FRONT_RIGHT_ACTION:
			controlled_camera->MoveForward(MOVE_INC_VALUE);
			controlled_camera->StrafeRight(MOVE_INC_VALUE);
			break;

		case KEYS_BACK_LEFT_ACTION:
			controlled_camera->MoveBackward(MOVE_INC_VALUE);
			controlled_camera->StrafeLeft(MOVE_INC_VALUE);
			break;

		case KEYS_BACK_RIGHT_ACTION:
			controlled_camera->MoveBackward(MOVE_INC_VALUE);
			controlled_camera->StrafeRight(MOVE_INC_VALUE);
			break;
	}
}

void MousePosCallback(GLFWwindow* window, double xpos, double ypos)
{
	//static int PressedKeys
	if (controlled_camera == NULL)
	{
		printf("erro: mousecallback: nenhuma camera ligada ao mouse\n");
		return;
	}

	glfwSetCursorPos(window,300,300);

	double xmove = (xpos-300);
	double ymove = (ypos-300);

	if (xmove != 0)
	{
		controlled_camera->TurnRight(xmove);
	}

	if (ymove != 0)
	{
		controlled_camera->LookDown(ymove);
	}
}